package mysql

import (
	"errors"
	"fmt"
	"gitee.com/captials-team/ubdframe/src/domain/configstc"
	"gitee.com/captials-team/ubdframe/src/domain/dto"
	"gitee.com/captials-team/ubdframe/src/domain/dto/paginate"
	"gitee.com/captials-team/ubdframe/src/domain/interfaces"
	"gitee.com/captials-team/ubdframe/src/domain/models"
	mysqlClients "gitee.com/captials-team/ubdframe/src/infrastructure/clients/mysql"
	"gitee.com/captials-team/ubdframe/src/pkg/logs"
	"gorm.io/gorm"
)

func NewMetricsDao(conf configstc.DBConfig) *MetricsDao {
	return &MetricsDao{
		db:   mysqlClients.NewGormDB(conf),
		conf: conf,
	}
}

type MetricsDao struct {
	db   *gorm.DB
	conf configstc.DBConfig
}

func (dao *MetricsDao) Search(search *dto.SearchMetricMetaDto, pa *paginate.Pager) ([]*models.Metrics, *paginate.Pager, error) {
	if search == nil {
		search = &dto.SearchMetricMetaDto{}
	}
	if pa == nil {
		pa = &paginate.Pager{}
	}
	pa.Correct()

	db := dao.db.Model(new(models.Metrics))

	var list []*models.Metrics

	if search.Keywords != "" {
		keywords := "%" + search.Keywords + "%"
		db = db.Where("(name like ?)", keywords, keywords)
	}

	if ret := db.Count(&pa.Total); ret.Error != nil {
		return list, pa, ret.Error
	}

	db = db.Order("id desc")
	if ret := db.Limit(pa.Size).Offset(pa.Offset()).Find(&list); ret.Error != nil {
		return list, pa, ret.Error
	}
	pa.Correct()
	return list, pa, nil
}

// AddOne 添加一个测点
func (dao *MetricsDao) AddOne(name string, extends string) (int64, error) {
	find := models.Metrics{
		Name:    name,
		Extends: extends,
	}
	ret := dao.db.Create(&find)
	if ret.Error != nil {
		return 0, ret.Error
	}
	return find.Id, nil
}

// Add 添加一个测点
func (dao *MetricsDao) Add(add *models.Metrics) (int64, error) {
	ret := dao.db.Create(&add)
	if ret.Error != nil {
		return 0, ret.Error
	}
	return add.Id, nil
}

// SubTableStrategy 分表策略
func (dao *MetricsDao) SubTableStrategy() func(int64) string {
	return func(id int64) string {
		metric, err := dao.Query(id)
		if err != nil {
			logs.Out.Error("query metric strategy %s", err)
			return ""
		}
		return metric.SplitKey
	}
}

// QueryByName 根据名称查询测点
func (dao *MetricsDao) QueryByName(name string) (*models.Metrics, error) {
	var find models.Metrics
	ret := dao.db.Where("name", name).First(&find)
	if errors.Is(ret.Error, gorm.ErrRecordNotFound) {
		return nil, nil
	}
	if ret.Error != nil {
		return nil, ret.Error
	}
	return &find, nil
}

// Query 根据id查询测点
func (dao *MetricsDao) Query(id int64) (*models.Metrics, error) {
	var find models.Metrics
	ret := dao.db.Where("id", id).First(&find)
	if errors.Is(ret.Error, gorm.ErrRecordNotFound) {
		return nil, nil
	}
	if ret.Error != nil {
		return nil, ret.Error
	}
	return &find, nil
}

// QueryMetricIdByName 根据名称查询测点id
func (dao *MetricsDao) QueryMetricIdByName(name string) (int64, error) {
	var find models.Metrics
	ret := dao.db.Where("name", name).Order("id desc").Select("id").First(&find)
	if errors.Is(ret.Error, gorm.ErrRecordNotFound) {
		return 0, nil
	}
	if ret.Error != nil {
		return 0, ret.Error
	}
	return find.Id, nil
}

// Delete 根据测点id进行删除
func (dao *MetricsDao) Delete(id int64) (int64, error) {
	ret := dao.db.Where("id=?", id).Delete(&models.Metrics{})
	if ret.Error != nil {
		return 0, ret.Error
	}
	if ret.RowsAffected == 0 {
		return 0, fmt.Errorf("no delete")
	}
	return ret.RowsAffected, nil
}

// Migrate 初始化表
func (dao *MetricsDao) Migrate() (int64, error) {
	return 1, dao.db.AutoMigrate(new(models.Metrics))
}

func (dao *MetricsDao) Use(db *gorm.DB) interfaces.ItfMetricMetaDao {
	return &MetricsDao{
		db:   db,
		conf: dao.conf,
	}
} //使用db

func (dao *MetricsDao) DB() *gorm.DB {
	return dao.db
} //使用db
